package cn.xuqiudong.sso.shiro;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.subject.Subject;

import java.util.Collections;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class ShiroSubjectSimulation {

    // 这里使用InheritableThreadLocal来模拟在子线程获取Subject的情况（有局限性）
    private static final InheritableThreadLocal<Subject> subjectThreadLocal = new InheritableThreadLocal<>();

    public static void main(String[] args) {
        // 1. 创建SecurityManager（这里是简化的，实际可能配置更复杂）
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        // 设置SecurityManager，这一步很关键，Shiro很多操作依赖它
        SecurityUtils.setSecurityManager(securityManager);
        // 添加自定义的Realm到SecurityManager中
        SimpleMemoryRealm realm = new SimpleMemoryRealm();
        securityManager.setRealms(Collections.singletonList(realm));

        // 2. 模拟登录
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken("user", "user");
        try {
            subject.login(token);
            System.out.println("登录成功");
            // 将登录后的Subject存储起来，方便后续获取（这里简单示例存储在自定义的ThreadLocal中）
            subjectThreadLocal.set(subject);
        } catch (Exception e) {
            System.out.println("登录失败: " + e.getMessage());
        }

        // 3. 模拟在线程中获取Subject
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 5; i++) {
            executorService.submit(() -> {
                Subject subInThread = subjectThreadLocal.get();
                if (subInThread!= null) {
                    System.out.println("子线程中获取到的Subject信息: " + subInThread.getPrincipal());
                } else {
                    System.out.println("子线程中未获取到Subject");
                }
            });
        }

        // 关闭线程池
        executorService.shutdown();
        try {
            if (executorService.awaitTermination(5, TimeUnit.SECONDS)) {
                System.out.println("线程任务执行完毕");
            } else {
                System.out.println("超时，部分线程任务可能未完成");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}